package com.fmatos.amazingwallpapers.view.albums;

import java.util.List;

import javax.inject.Inject;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
import android.widget.Toast;

import com.fmatos.amazingwallpapers.R;
import com.fmatos.amazingwallpapers.image.AsyncCloudManager;
import com.fmatos.amazingwallpapers.imagemanagement.FileManager;
import com.fmatos.amazingwallpapers.imagemanagement.FileNotAvailableException;
import com.fmatos.amazingwallpapers.view.album.AlbumActivity;
import com.fmatos.amazingwallpapers.view.albums.AlbumsViewSource.AlbumViewDto;
import com.fmatos.amazingwallpapers.view.detail.ImageDetail;

/**
 * Responsible for interacting with {@link AlbumsViewSource}, inflating view
 * and populating it, and also sending/asking info to service (when a thumbnail is missing).
 * @author fdematos
 *
 */
public class AlbumsAdapter
extends BaseAdapter {

	private static final String TAG = AlbumsAdapter.class.getSimpleName();
	private static final DateTimeFormatter FORMATTER_HOUR_MINUTE_SECOND = DateTimeFormat.forPattern("HH:mm:ss");
	private static final DateTimeFormatter FORMATTER_DAY_MONTH_YEAR = DateTimeFormat.forPattern("dd/MM/yyyy");
	
	
	private List<AlbumViewDto> values;
	private LayoutInflater mIInflater;

	private AsyncCloudManager asyncCloudManager;
	

	private FileManager fileManager;
	
	private AlbumsViewSource albumSource;
	private Context context;

	@Inject
	public AlbumsAdapter(Context context, 
			AlbumsViewSource albumSource, 
			FileManager fileManager,
			AsyncCloudManager asyncCloudManager) {
		this.context = context;
		
		this.asyncCloudManager = asyncCloudManager;
//		asyncCloudManager = //new AsyncCloudManager(context);

		this.fileManager = fileManager;
		this.albumSource = albumSource;
		
		mIInflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		notifyDataSetChanged();
	}

	
	@Override
	public void notifyDataSetChanged() {
	
		values = albumSource.getAlbumList();
		super.notifyDataSetChanged();
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		ViewHolder viewHolder = viewHolderPattern(position,convertView,parent);

		resetView(viewHolder);
		
		AlbumViewDto albumDTO = (AlbumViewDto) this.getItem(position);
		if ( albumDTO != null ) {
			createListeners(viewHolder,albumDTO);
			populateView(viewHolder,albumDTO);
				
		}

		return viewHolder.view;
	}

	private void populateView(ViewHolder viewHolder, AlbumViewDto albumDTO) {
		
		if ( albumDTO == null ) {
			return;
		}
		
		viewHolder.txtNiceName.setText(albumDTO.niceName);
		Log.d(TAG,albumDTO.niceName + " has #" + albumDTO.photoCount + " photos");
		viewHolder.txtPhotoCount.setText(Integer.toString(albumDTO.photoCount));
		
		if ( albumDTO.updateTime != null ) {
			
			viewHolder.txtTimestamp.setText(formatDate(albumDTO.updateTime)); // TODO parse date
		} else {
			viewHolder.txtTimestamp.setText("Unknown");
		}

		drawFavoriteStar(albumDTO,viewHolder.btnFavorite);
		loadThumbnail(viewHolder,albumDTO);
		
	}

	/**
	 * Loads thumbnail if it's already cached, and download and set it otherwise
	 * @param viewHolder 
	 * @param albumDTO
	 */
	private void loadThumbnail(ViewHolder viewHolder, AlbumViewDto albumDTO) {
		if ( ! loadPhotoFromDisk(viewHolder,albumDTO)) {
			if  (! albumDTO.thumbnailIsDownloading ) {
				albumDTO.thumbnailIsDownloading = true;
			
				asyncCloudManager.getPhotoFromNetwork(albumDTO.thumbnailUrl,new Runnable() {
					@Override
					public void run() {
						notifyDataSetChanged();
					}
				});
			}
		}
			
	}
	
	/**
	 * 
	 * @param viewHolder
	 * @param albumDTO
	 * @return return true if photo is loaded successfully
	 */
	private boolean loadPhotoFromDisk(ViewHolder viewHolder, AlbumViewDto albumDTO) {
		if ( albumDTO.thumbnailFile != null ) {
			Bitmap bm = null;
			try {
				bm = fileManager.loadThumbnailFromPath(albumDTO.thumbnailFile);
			} catch (FileNotAvailableException e) {
				Log.w(TAG,"Must mark image as invalid " + albumDTO.niceName + " file " + albumDTO.thumbnailFile);
			}

			if ( bm != null ) {
				viewHolder.imageView.setScaleType(ScaleType.CENTER_CROP);
				viewHolder.imageView.setImageBitmap(bm);
				return true;
			}
		}
		
		return false;
		
	}

	private CharSequence formatDate(DateTime updateTime) {
		
		if ( updateTime.getMillis() == 0) {
			return "never";
		}
		
		if (updateTime.plusDays(1).isAfterNow()) {
			return FORMATTER_HOUR_MINUTE_SECOND.print(updateTime);
		} else {
			return FORMATTER_DAY_MONTH_YEAR.print(updateTime);
		}
		
	}

	private void setImageListener(ImageView imgView,final String albumId, final String url) {
		
		imgView.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Log.i(TAG, "I dont want to click on the image album" + albumId);
				
				Toast.makeText(context, "Click item "  , Toast.LENGTH_SHORT).show();

				Intent intent = new Intent(context,AlbumActivity.class);
				intent.putExtra(ImageDetail.INTENT_EXTRA_ALBUM_ID, albumId);

				context.startActivity(intent);		
			}
		});
		
		imgView.setFocusable(false);
		
	}
	
	private ViewHolder viewHolderPattern(int position, View convertView, ViewGroup parent) {
		View view;
		ViewHolder holder;
		if(convertView == null ) {
			view = mIInflater.inflate(R.layout.albums_row, parent, false);
			holder = new ViewHolder();
			holder.view = view;
			holder.txtNiceName = (TextView)view.findViewById(R.id.txtAlbumName);
			holder.txtPhotoCount = (TextView)view.findViewById(R.id.txtAvailableImages);
			holder.imageView =  (ImageView)view.findViewById(R.id.imgAlbumThumbnail);
			holder.btnUpdate = (ImageButton) view.findViewById(R.id.imgBtUpdateAlbum);
			holder.btnFavorite = (ImageButton) view.findViewById(R.id.imgBtFavoriteAlbum);
			holder.txtTimestamp = (TextView) view.findViewById(R.id.txtTimestamp);
			
			view.setTag(holder);
		} else {
		
			holder = (ViewHolder)convertView.getTag();

		}
		
		return holder;
	}

	private void createListeners(ViewHolder holder, final AlbumViewDto albumDto) {

		final Drawable drawableFinished = context.getResources().getDrawable(R.drawable.ic_menu_refresh);
		final Drawable drawableBusy = context.getResources().getDrawable(android.R.drawable.stat_sys_download);
		final ImageButton button = holder.btnUpdate;

		
		button.setImageDrawable(drawableFinished); // TODO this must depende on viewholder download state
		
		button.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				button.setImageDrawable(drawableBusy);
				albumSource.updateAlbumInfo(albumDto, new Runnable() {
					
					@Override
					public void run() {	
						button.setImageDrawable(drawableFinished);
					}
				});
			}
		});
			
	}
	
	private void drawFavoriteStar(final AlbumViewDto albumDto,final ImageButton btnFavorite) {

		int starId = albumDto.favorite ? android.R.drawable.star_big_on : android.R.drawable.star_big_off;
		Drawable starredAlbum = context.getResources().getDrawable(starId );
		btnFavorite.setImageDrawable(starredAlbum);
		
		if ( ! btnFavorite.hasOnClickListeners() ) {
			btnFavorite.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					if ( albumSource.setFavorite(albumDto,!albumDto.favorite) ) {
						albumDto.favorite = !albumDto.favorite;
						drawFavoriteStar(albumDto, btnFavorite);
					}
				}
			});
		}
		
	}

	private void resetView(ViewHolder holder) {
		holder.txtNiceName.setText("");
		holder.txtPhotoCount.setText("0");
		
		holder.imageView.setScaleType(ScaleType.CENTER_INSIDE);
		holder.imageView.setImageResource(R.drawable.ic_launcher);
		holder.imageView.setFocusable(false); // allows buttons to receive click events
		holder.imageView.setOnClickListener(null);
		
		holder.btnFavorite.setOnClickListener(null);
		holder.btnUpdate.setOnClickListener(null);
	}


	@Override
	public int getCount() {
		return values.size();
	}

	@Override
	public Object getItem(int position) {
		if ( values != null && values.size() > position ) {
			return values.get(position);
		} else {
			return null;
		}
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	private class ViewHolder {
		
		public View view;
		public ImageButton btnFavorite;
		public ImageButton btnUpdate;
		public ImageView imageView;
		
		public TextView txtPhotoCount;
		public TextView txtNiceName;
		public TextView txtTimestamp;
	}

	public void releaseResources() {
		albumSource.releaseResouces();
	}

}
